package com.nutrition.health.controller;

import com.nutrition.health.model.DietRecord;
import com.nutrition.health.model.DietRecord.MealType;
import com.nutrition.health.model.FoodItem;
import com.nutrition.health.model.FoodItem.FoodCategory;
import com.nutrition.health.repository.DietRecordRepository;
import com.nutrition.health.service.DietRecordService;
import com.nutrition.health.service.FoodItemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/users/{userId}/diet-records")
@Api(tags = "饮食记录", description = "用户饮食记录和营养摄入分析相关操作")
@CrossOrigin(origins = "*")
public class DietRecordController {

    private final DietRecordService dietRecordService;
    private final FoodItemService foodItemService;
    private final DietRecordRepository dietRecordRepository;

    @Autowired
    public DietRecordController(DietRecordService dietRecordService,
                               FoodItemService foodItemService,
                               DietRecordRepository dietRecordRepository) {
        this.dietRecordService = dietRecordService;
        this.foodItemService = foodItemService;
        this.dietRecordRepository = dietRecordRepository;
    }

    @GetMapping
    @ApiOperation("获取用户的所有饮食记录")
    public ResponseEntity<Page<DietRecord>> getAllDietRecords(
            @PathVariable Long userId,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "consumptionTime") String sortBy,
            @RequestParam(defaultValue = "DESC") String sortDir) {

        Sort.Direction direction = Sort.Direction.fromString(sortDir);
        Pageable pageable = PageRequest.of(page, size, Sort.by(direction, sortBy));

        Page<DietRecord> dietRecords = dietRecordService.getAllDietRecordsByUserId(userId, pageable);
        return new ResponseEntity<>(dietRecords, HttpStatus.OK);
    }

    @GetMapping("/{id}")
    @ApiOperation("根据ID获取饮食记录")
    public ResponseEntity<DietRecord> getDietRecordById(@PathVariable Long id) {
        return dietRecordService.getDietRecordById(id)
                .map(dietRecord -> new ResponseEntity<>(dietRecord, HttpStatus.OK))
                .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @GetMapping("/meal-type/{mealType}")
    @ApiOperation("根据餐食类型获取饮食记录")
    public ResponseEntity<List<DietRecord>> getDietRecordsByMealType(
            @PathVariable Long userId,
            @PathVariable MealType mealType) {

        List<DietRecord> dietRecords = dietRecordService.getDietRecordsByUserIdAndMealType(userId, mealType);
        return new ResponseEntity<>(dietRecords, HttpStatus.OK);
    }

    @GetMapping("/date-range")
    @ApiOperation("根据日期范围获取饮食记录")
    public ResponseEntity<List<DietRecord>> getDietRecordsByDateRange(
            @PathVariable Long userId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {

        List<DietRecord> dietRecords = dietRecordService.getDietRecordsByUserIdAndDateRange(
                userId, startDate, endDate);

        return new ResponseEntity<>(dietRecords, HttpStatus.OK);
    }

    @PostMapping
    @ApiOperation("创建新的饮食记录")
    public ResponseEntity<DietRecord> createDietRecord(
            @PathVariable Long userId,
            @Valid @RequestBody DietRecord dietRecord) {

        DietRecord createdDietRecord = dietRecordService.createDietRecord(userId, dietRecord);
        return new ResponseEntity<>(createdDietRecord, HttpStatus.CREATED);
    }

    @PutMapping("/{id}")
    @ApiOperation("更新饮食记录")
    public ResponseEntity<DietRecord> updateDietRecord(
            @PathVariable Long id,
            @Valid @RequestBody DietRecord dietRecordDetails) {

        DietRecord updatedDietRecord = dietRecordService.updateDietRecord(id, dietRecordDetails);
        return new ResponseEntity<>(updatedDietRecord, HttpStatus.OK);
    }

    @DeleteMapping("/{id}")
    @ApiOperation("删除饮食记录")
    public ResponseEntity<Void> deleteDietRecord(@PathVariable Long id) {
        dietRecordService.deleteDietRecord(id);
        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
    }

    @PostMapping("/{dietRecordId}/food-items/{foodItemId}")
    @ApiOperation("添加食品到饮食记录")
    public ResponseEntity<DietRecord> addFoodItemToDietRecord(
            @PathVariable Long dietRecordId,
            @PathVariable Long foodItemId) {

        DietRecord updatedDietRecord = dietRecordService.addFoodItemToDietRecord(dietRecordId, foodItemId);
        return new ResponseEntity<>(updatedDietRecord, HttpStatus.OK);
    }

    @DeleteMapping("/{dietRecordId}/food-items/{foodItemId}")
    @ApiOperation("从饮食记录中移除食品")
    public ResponseEntity<DietRecord> removeFoodItemFromDietRecord(
            @PathVariable Long dietRecordId,
            @PathVariable Long foodItemId) {

        DietRecord updatedDietRecord = dietRecordService.removeFoodItemFromDietRecord(dietRecordId, foodItemId);
        return new ResponseEntity<>(updatedDietRecord, HttpStatus.OK);
    }

    @GetMapping("/total-calories")
    @ApiOperation("计算用户在指定日期范围内的总卡路里摄入")
    public ResponseEntity<Map<String, Double>> calculateTotalCalories(
            @PathVariable Long userId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {

        double totalCalories = dietRecordService.calculateTotalCaloriesForUserInDateRange(
                userId, startDate, endDate);
        Map<String, Double> calories = new HashMap<>();
        calories.put("totalCalories", totalCalories);
        return new ResponseEntity<>(calories, HttpStatus.OK);
    }

    @GetMapping("/nutrient-intake")
    @ApiOperation("计算用户在指定日期范围内的营养素摄入")
    public ResponseEntity<Map<String, Double>> calculateNutrientIntake(
            @PathVariable Long userId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {

        Map<String, Double> nutrientIntake = dietRecordService.calculateNutrientIntakeForUserInDateRange(
                userId, startDate, endDate);

        return new ResponseEntity<>(nutrientIntake, HttpStatus.OK);
    }

    @GetMapping("/dietary-patterns")
    @ApiOperation("分析用户的饮食模式")
    public ResponseEntity<Map<String, Object>> analyzeDietaryPatterns(
            @PathVariable Long userId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {

        Map<String, Object> dietaryPatterns = dietRecordService.analyzeDietaryPatterns(
                userId, startDate, endDate);

        return new ResponseEntity<>(dietaryPatterns, HttpStatus.OK);
    }
@GetMapping("/nutrition-comparison")
@ApiOperation("获取用户在指定周期内的营养素摄入与推荐值对比数据")
public ResponseEntity<Map<String, Object>> getNutritionComparison(
        @PathVariable Long userId,
        @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date,
        @RequestParam(defaultValue = "weekly") String period) {

    Map<String, Object> nutritionComparison = dietRecordService.getNutritionComparison(userId, date, period);
    return new ResponseEntity<>(nutritionComparison, HttpStatus.OK);
}

@GetMapping("/calorie-goal")
@ApiOperation("获取用户在指定日期的热量摄入目标完成情况")
public ResponseEntity<Map<String, Object>> getCalorieGoalCompletion(
        @PathVariable Long userId,
        @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) {

    Map<String, Object> calorieGoalCompletion = dietRecordService.getCalorieGoalCompletion(userId, date);
    return new ResponseEntity<>(calorieGoalCompletion, HttpStatus.OK);
}

@GetMapping("/nutrition-ratio")
@ApiOperation("获取用户在指定日期的营养素占比数据")
public ResponseEntity<Map<String, Object>> getNutritionRatio(
        @PathVariable Long userId,
        @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date,
        @RequestParam(defaultValue = "daily") String period) {

    Map<String, Object> nutritionRatio = dietRecordService.getNutritionRatio(userId, date, period);
    return new ResponseEntity<>(nutritionRatio, HttpStatus.OK);
}

@GetMapping("/nutrition-trend")
@ApiOperation("获取用户在指定日期范围内的营养趋势数据")
public ResponseEntity<Map<String, Object>> getNutritionTrend(
        @PathVariable Long userId,
        @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
        @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {

    Map<String, Object> nutritionTrend = dietRecordService.getNutritionTrend(userId, startDate, endDate);
    return new ResponseEntity<>(nutritionTrend, HttpStatus.OK);
}

@GetMapping("/compare-intake")
@ApiOperation("比较用户的实际营养摄入与推荐摄入")
public ResponseEntity<Map<String, Object>> compareActualVsRecommendedIntake(
        @PathVariable Long userId,
        @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) {

    Map<String, Object> comparison = dietRecordService.compareActualVsRecommendedIntake(userId, date);
    return new ResponseEntity<>(comparison, HttpStatus.OK);
}

@GetMapping("/meal-nutrition")
@ApiOperation("获取指定日期各餐食类型的营养摄入统计")
public ResponseEntity<Map<String, Object>> getMealNutritionStats(
        @PathVariable Long userId,
        @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) {
    
    LocalDateTime startDateTime = date.atStartOfDay();
    LocalDateTime endDateTime = date.atTime(LocalTime.MAX);
    
    Map<String, Object> mealStats = new HashMap<>();
    
    // 获取各餐食类型的记录
    for (MealType mealType : MealType.values()) {
        List<DietRecord> mealRecords = dietRecordRepository.findByUserIdAndMealTypeAndConsumptionTimeBetween(
                userId, mealType, startDateTime, endDateTime);
        
        // 计算该餐食类型的总卡路里
        Double totalCalories = dietRecordRepository.calculateTotalCaloriesByMealType(
                userId, mealType, startDateTime, endDateTime);
        
        // 如果没有数据，设置为0
        if (totalCalories == null) {
            totalCalories = 0.0;
        }
        
        // 创建该餐食类型的统计数据
        Map<String, Object> mealData = new HashMap<>();
        mealData.put("calories", totalCalories);
        mealData.put("recordCount", mealRecords.size());
        
        // 添加到结果中
        mealStats.put(mealType.toString(), mealData);
    }
    
    return new ResponseEntity<>(mealStats, HttpStatus.OK);
}

    @GetMapping("/meal-types")
    @ApiOperation("获取所有餐食类型")
    public ResponseEntity<MealType[]> getAllMealTypes() {
        return new ResponseEntity<>(MealType.values(), HttpStatus.OK);
    }
    
    @PostMapping("/{dietRecordId}/food-items")
    @ApiOperation("添加食品到饮食记录（通过食品名称）")
    public ResponseEntity<DietRecord> addFoodItemByName(
            @PathVariable Long userId,
            @PathVariable Long dietRecordId,
            @RequestBody Map<String, Object> foodData) {
        
        try {
            // 从请求体中获取食品名称和数量
            String foodName = (String) foodData.get("name");
            Double amount = Double.parseDouble(foodData.get("amount").toString());
            
            // 查找是否已存在该食品
            List<FoodItem> existingFoodItems = foodItemService.searchFoodItems(foodName, PageRequest.of(0, 1)).getContent();
            FoodItem foodItem;
            
            if (!existingFoodItems.isEmpty()) {
                // 如果存在，使用现有食品
                foodItem = existingFoodItems.get(0);
            } else {
                // 如果不存在，创建新食品
                foodItem = new FoodItem();
                foodItem.setName(foodName);
                
                // 根据名称猜测食品类别
                FoodCategory category = guessFoodCategory(foodName);
                foodItem.setCategory(category);
                
                // 保存新食品
                foodItem = foodItemService.createFoodItem(foodItem);
            }
            
            // 添加食品到饮食记录
            DietRecord updatedRecord = dietRecordService.addFoodItemToDietRecord(dietRecordId, foodItem.getId());
            return new ResponseEntity<>(updatedRecord, HttpStatus.OK);
            
        } catch (Exception e) {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
    /**
     * 根据食品名称猜测食品类别
     * @param foodName 食品名称
     * @return 猜测的食品类别
     */
    private FoodCategory guessFoodCategory(String foodName) {
        String lowerName = foodName.toLowerCase();
        
        // 水果
        if (lowerName.contains("苹果") || lowerName.contains("香蕉") || lowerName.contains("橙") ||
            lowerName.contains("梨") || lowerName.contains("草莓") || lowerName.contains("水果")) {
            return FoodCategory.FRUITS;
        }
        
        // 蔬菜
        if (lowerName.contains("菜") || lowerName.contains("西红柿") || lowerName.contains("黄瓜") ||
            lowerName.contains("胡萝卜") || lowerName.contains("生菜") || lowerName.contains("蔬菜")) {
            return FoodCategory.VEGETABLES;
        }
        
        // 谷物
        if (lowerName.contains("米") || lowerName.contains("面") || lowerName.contains("麦") ||
            lowerName.contains("粥") || lowerName.contains("饭") || lowerName.contains("谷物")) {
            return FoodCategory.GRAINS;
        }
        
        // 蛋白质食品
        if (lowerName.contains("肉") || lowerName.contains("鸡") || lowerName.contains("牛") ||
            lowerName.contains("猪") || lowerName.contains("鱼") || lowerName.contains("蛋") ||
            lowerName.contains("豆腐") || lowerName.contains("豆")) {
            return FoodCategory.PROTEINS;
        }
        
        // 乳制品
        if (lowerName.contains("奶") || lowerName.contains("酸奶") || lowerName.contains("奶酪") ||
            lowerName.contains("乳") || lowerName.contains("酪")) {
            return FoodCategory.DAIRY;
        }
        
        // 零食
        if (lowerName.contains("零食") || lowerName.contains("饼干") || lowerName.contains("薯片") ||
            lowerName.contains("巧克力") || lowerName.contains("糖")) {
            return FoodCategory.SNACKS;
        }
        
        // 饮料
        if (lowerName.contains("水") || lowerName.contains("茶") || lowerName.contains("咖啡") ||
            lowerName.contains("饮料") || lowerName.contains("汁") || lowerName.contains("酒")) {
            return FoodCategory.BEVERAGES;
        }
        
        // 默认为其他
        return FoodCategory.OTHER;
    }
    
    @PostMapping("/with-food-items")
    @ApiOperation("创建饮食记录并同时添加多个食品（一次性计算营养信息）")
    public ResponseEntity<DietRecord> createDietRecordWithFoodItems(
            @PathVariable Long userId,
            @Valid @RequestBody Map<String, Object> requestData) {
        
        try {
            // 从请求体中提取饮食记录数据
            Map<String, Object> dietRecordData = (Map<String, Object>) requestData.get("dietRecord");
            List<Map<String, Object>> foodItems = (List<Map<String, Object>>) requestData.get("foodItems");
            
            if (dietRecordData == null || foodItems == null) {
                return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
            }
            
            // 创建饮食记录对象
            DietRecord dietRecord = new DietRecord();
            
            // 设置饮食记录属性
            if (dietRecordData.get("consumptionTime") != null) {
                // 处理ISO格式的日期时间字符串，去掉可能的毫秒和时区信息
                String dateTimeStr = dietRecordData.get("consumptionTime").toString();
                // 如果包含小数点（毫秒），截取到秒
                if (dateTimeStr.contains(".")) {
                    dateTimeStr = dateTimeStr.substring(0, dateTimeStr.indexOf("."));
                }
                // 如果包含Z（UTC时区标识），去掉
                if (dateTimeStr.endsWith("Z")) {
                    dateTimeStr = dateTimeStr.substring(0, dateTimeStr.length() - 1);
                }
                dietRecord.setConsumptionTime(LocalDateTime.parse(dateTimeStr));
            }
            
            if (dietRecordData.get("mealType") != null) {
                dietRecord.setMealType(MealType.valueOf(dietRecordData.get("mealType").toString()));
            }
            
            if (dietRecordData.get("notes") != null) {
                dietRecord.setNotes(dietRecordData.get("notes").toString());
            }
            
            // 调用服务层方法创建饮食记录并添加食品
            DietRecord createdDietRecord = dietRecordService.createDietRecordWithFoodItems(userId, dietRecord, foodItems);
            
            return new ResponseEntity<>(createdDietRecord, HttpStatus.CREATED);
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
    @GetMapping("/food-category-distribution")
    @ApiOperation("获取用户在指定周期内的食物类型摄入分布数据")
    public ResponseEntity<Map<String, Object>> getFoodCategoryDistribution(
            @PathVariable Long userId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date,
            @RequestParam(defaultValue = "weekly") String period) {
        
        Map<String, Object> foodCategoryDistribution = dietRecordService.getFoodCategoryDistribution(userId, date, period);
        return new ResponseEntity<>(foodCategoryDistribution, HttpStatus.OK);
    }
    
    @GetMapping("/bmi-trend")
    @ApiOperation("获取用户在指定日期范围内的BMI趋势数据")
    public ResponseEntity<Map<String, Object>> getBMITrend(
            @PathVariable Long userId,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
        
        Map<String, Object> bmiTrend = dietRecordService.getBMITrend(userId, startDate, endDate);
        return new ResponseEntity<>(bmiTrend, HttpStatus.OK);
    }
}